﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TeamOPSchoolCup.Domain.POCO;
using TeamOPSchoolCup.Domain.DAL;
using TeamOPSchoolCup.Domain.POCO.Members;
using System.Collections;
using System.Data;
namespace TeamOPSchoolCup.Domain.Services
{
  public class RegionService
  {
    public static List<Region> GetRegionsByHierarchy(bool sort)
    {
      List<Region> r;
      using (EFDbContext db = new EFDbContext())
      {
        r = GetRegionsByHierarchy(db, sort);
      }
      return r;
    }

    public static List<Region> GetRegionsByHierarchy(EFDbContext db, bool sort)
    {
      List<Region> regions = new List<Region>();
      foreach (Region r in GetContinents(db, sort))
      {
        getRegionsByHierarchyPart(r, sort, ref regions);
      }
      return regions;
    }

    private static void getRegionsByHierarchyPart(Region r, bool sort, ref List<Region> list)
    {
      list.Add(r);
      foreach (Region r2 in (sort ? SortRegions(r.Children) : r.Children)) { getRegionsByHierarchyPart(r2, sort, ref list); }
    }

    //This list will give the Region Tree which means the hierarchic strucure of the Region
    /*public List<Region> GetRegionTree(bool sort)
    {
      List<Region> regions = new List<Region>();

      foreach (Region r in this.SortRegions(GetContinents(true)))
      {
        r.Children = this.SortRegions(r.Children);
        regions.Add(r);
        foreach (Region re in r.Children)
        {
          re.Children = this.SortRegions(re.Children);
          regions.Add(re);
          foreach (Region reg in re.Children)
          {
            regions.Add(reg);
          }
        }
      }

      return regions;
    }*/

    public static List<Region> GetRegionTree(bool sort)
    {
      return GetAllRegions();
    }

    public static List<Region> GetContinents(bool sort)
    {
      List<Region> continents;
      using (EFDbContext db = new EFDbContext())
      {
        continents = GetContinents(db, sort);
      }

      return continents;
    }

    public static List<Region> GetContinents(EFDbContext db, bool sort)
    {
      List<Region> regions = db.Regions.Where(r => r.ParentId == null).ToList();
      if (sort) regions = SortRegions(regions);
      return regions;
    }

    public static List<Region> GetCountries(bool sort)
    {
      List<Region> countries;
      using (EFDbContext db = new EFDbContext())
      {
        countries = GetCountries(db, sort);
      }

      return countries;
    }

    public static List<Region> GetCountries(EFDbContext db, bool sort)
    {
      return db.Regions.Where(r => r.Parent.ParentId == null).ToList();
    }

    public static List<Region> GetRegions()
    {
      List<Region> regions;
      using (EFDbContext db = new EFDbContext())
      {
        regions = GetRegions(db);
      }

      return regions;
    }

    //This will give the regions and not the full region table
    public static List<Region> GetRegions(EFDbContext db)
    {
      return db.Regions.Where(r => r.Parent.Parent.ParentId == null).ToList();
    }

    //This will ASC sort the table 
    public static List<Region> SortRegions(List<Region> regions)
    {
      regions.Sort();
      return regions;
    }

    public static List<Region> GetAllRegions()
    {
      List<Region> regions;
      using (EFDbContext db = new EFDbContext())
      {
        regions = GetAllRegions(db);
      }

      return SortRegions(regions);
    }

    public static List<Region> GetAllRegions(EFDbContext db)
    {
      return db.Regions.ToList();
    }

    public static List<Region> GetChildren(Region region)
    {
      List<Region> children;
      using (EFDbContext db = new EFDbContext())
      {
        children = GetChildren(db, region);
      }

      return children;
    }

    public static List<Region> GetChildren(EFDbContext db, Region region)
    {
      List<Region> children = db.Regions.Where(r => r.ParentId == region.RegionId).ToList();
      return children;
    }

    public static Region GetParent(Region region)
    {
      Region parent;
      using (EFDbContext db = new EFDbContext())
      {
        parent = GetParent(db, region);
      }

      return parent;
    }

    public static Region GetParent(EFDbContext db, Region region)
    {
      return db.Regions.Where(r => r.ParentId == region.RegionId).First();
    }

    public static bool AddRegion(Region region)
    {
      bool r;
      using (EFDbContext db = new EFDbContext())
      {
        r = AddRegion(db, region);
      }

      return r;
    }

    public static bool AddRegion(EFDbContext db, Region region)
    {
      db.Regions.Add(region);

      return (db.SaveChanges() > 0);
    }

    public static bool AddRegion(string regionName, string parentName)
    {
      bool r;
      using (EFDbContext db = new EFDbContext())
      {
        r = AddRegion(db, regionName, parentName);
      }

      return r;
    }

    public static bool AddRegion(EFDbContext db, string regionName, string parentName)
    {
      db.Regions.Add(new Region { Name = regionName, Parent = db.Regions.Where(r => r.Name == parentName).First() });
      return db.SaveChanges() > 0 ? true : false;
    }

    public static Region GetRegion(string regionName)
    {
      Region r;
      using (EFDbContext db = new EFDbContext())
      {
        r = GetRegion(db, regionName);
      }
      return r;
    }

    public static Region GetRegion(EFDbContext db, string regionName)
    {
      return db.Regions.Where(x => x.Name.Equals(regionName)).FirstOrDefault();
    }

    public static Region GetRegion(int regionId)
    {
      Region r;
      using (EFDbContext db = new EFDbContext())
      {
        r = GetRegion(db, regionId);
      }

      return r;
    }

    public static Region GetRegion(EFDbContext db, int regionId)
    {
      return db.Regions.Find(regionId);
    }

    public static bool UpdateRegion(Region region)
    {
      bool r;
      using(EFDbContext db = new EFDbContext()){
        r = UpdateRegion(db, region);
      }

      return r;
    }

    public static bool UpdateRegion(EFDbContext db, Region region)
    {
      db.Entry(region).State = EntityState.Modified;

      return (db.SaveChanges() > 0);
    }
  }
}
